/* 
 该模块 禁止在 api/index.ts 以外的文件调用
  merak 2.0  登录token以及令牌加密设置所有请求 的请求头。
  X-Api-Access-Token:登录后用户token，
  X-Api-ClientId:merak2.0系统唯一识别id 
  X-Api-Nonce:8位随机数，
  X-Api-Signature:接口令牌 加密规则 base64(HmacSHA256())：curRouter + Nonce + TimeStamp, key：登录前ClientId 登录后 Clientsecret 
  X-Api-Timestamp:时间戳
  X-Api-Clientsecret: appKey 用于令牌关键字
  接口令牌、8位随机数、时间戳每次请求都不一样
*/


import axios from "axios";
import CryptoJS from 'crypto-js';
import { AES128 } from "@/api/modules/encryption";
import { encode, decode } from 'js-base64';
import { appId } from "@/config";
import { PORT1 } from "@/api/config/servicePort";
import { useUserStore } from "@/stores/modules/user";
import { concat } from "mathjs";


const getAppKeyApi: string = '/api-auth/index';
const renewApi: string = '/api-auth/renew';
const nonceNum: number = 99999999;
// let renewTimeThreshold = 1000*60*60;//刷新token时间范围 1小时
let renewTimeThreshold = 1000 * 60 * 60 *3;//刷新token时间 3小时


class CheckToken {
  config;
  clientSecret;
  public constructor() {
    // this.config = {};
    this.clientSecret = null;
  }

  getXToken(url: string): any {
    //获取全部的 请求头信息 
    let token = useUserStore().token;
    let Nonce = this.getNonce();
    let TimeStamp = this.getTimeStamp();
    let Signature = this.getSignature(Nonce, TimeStamp, this.getPath(url), this.clientSecret || appId);
    let config = {
      headers: {
        'X-Api-ClientId': appId,
        'X-Api-Nonce': Nonce,
        'X-Api-TimeStamp': TimeStamp,
        'X-Api-Signature': Signature,
      },
      loading: false
    }
    if (this.clientSecret) {//如果已经获取到了clientSecret，删除ClientId
      delete config.headers['X-Api-ClientId'];
      // this.config.headers['X-Api-ClientSecret'] = this.clientSecret;
    }
    if (token) {//如果 已经登录(来自 store)，设置token
      config.headers['X-Api-access-token'] = token;
    }
    return config
  }

  async getAppKey() {
    const instance = axios.create();
    //获取appKey 用于所有请求头携带的 X-Api-Clientsecret 
    let _this = this;
    if (_this.clientSecret) {//已经获取，直接返回
      return _this.clientSecret
    }

    await new Promise((resolve, reject) => {
      instance.interceptors.request.use(config => {
        config.headers = {
          ...config.headers, ..._this.getXToken(`${PORT1}${getAppKeyApi}`).headers
        }
        return config
      })
      resolve()
    })

    //使用加密令牌 获取clientSecret appKey  
    await new Promise((resolve, reject) => {
      instance.post(`${PORT1}${getAppKeyApi}`).then(res => {
        _this.clientSecret = res.data.data.app_key;
        resolve()
      })
    })

    return Promise.resolve()
  }
  getTimeStamp(): number {//获取时间戳随机数
    // X-Api-TimeStamp
    const stamp = Math.round(Math.random() * new Date().getTime());
    return stamp;
  }

  getNonce(): string {//获取8位随机数
    let nonce: string = '';
    while (nonce.length != 8) {
      random();
    }
    function random(): void {
      nonce = Math.round(Math.random() * nonceNum) + '';
    }
    return nonce
  }

  getSignature(Nonce, TimeStamp, url, key) {
    let cryptoResult = CryptoJS.HmacSHA256(url + Nonce + TimeStamp, key).toString();
    let resultData = encode(cryptoResult);
    return resultData
  }
  getPath(url: string): string {
    return new URL(url).pathname
  }

  //续约专用请求头
  renewXToken(url) {
    //获取全部的 请求头信息 
    let token = useUserStore().token;
    let refreshtoken = useUserStore().userInfo.refresh_access_token || '';
    let Nonce = this.getNonce();
    let TimeStamp = this.getTimeStamp();
    let Signature = this.getSignature(Nonce, TimeStamp, this.getPath(url), this.clientSecret);

    let config = {
      headers: {
        'X-Api-ClientId': appId,
        'X-Api-Nonce': Nonce,
        'X-Api-TimeStamp': TimeStamp,
        'X-Api-Signature': Signature,
        'X-Api-Refresh-Access-Token': refreshtoken,
        // 'X-Signature': `${Nonce}, ${TimeStamp}, ${this.getPath(url)}, ${this.clientSecret}`
      },
      loading: false
    }

    if (token) {//如果 已经登录(来自 store)，设置token
      config.headers['X-Api-access-token'] = token;
    }
    return config

  }
  //续约接口
  async renew(url: string) {

    let _this = this;
    let userId = useUserStore().userInfo.id || '';
    let newConfig = _this.renewXToken(`${PORT1}${renewApi}`).headers;
    let newToken = '';
    await new Promise((resolve, reject) => {
      axios({
        method: 'post',
        url: `${PORT1}${renewApi}`,
        headers: newConfig,
        synchronous: true,
        data: { id: AES128(JSON.stringify(userId)) }
      }).then(res => {
        console.log(res);
        let userInfo = useUserStore();
        userInfo.setToken(res.data.data.access_token)
        newToken = res.data.data.access_token
        resolve({ token: res.data.data.access_token })
      });
    })

    return Promise.resolve(newToken);

  }
  //启动续约定时器 主函数
  initRenewTimer() {
    
    //已经启动不在设置
    const _this = this;
    if (window['renewTimerIs']) {
      return
    }
    console.log(`启动续约定时器,${renewTimeThreshold} ms后执行`)
    window['renewTimerIs'] = true;
    window['timeStamp'] = new Date().getTime();
    window.renewTimer = setInterval(() => {
      let userInfo = useUserStore();
      let curTimeStamp = new Date().getTime();
      let timeDiff = curTimeStamp - window['timeStamp'];
      if (curTimeStamp - window['timeStamp'] < renewTimeThreshold) {
        return
      }
      if (userInfo.token) {//已经登录
        _this.renew(`${PORT1}${renewApi}`).then((res) => {
          console.log("续约成功，新的token");
          window['timeStamp'] = curTimeStamp;
        }).catch(err => {
        })
      } else {

      }
    }, 2000);
  }

}
let checkTokenInstance = null;
if (window['checkTokenInstance']) {
  checkTokenInstance = window['checkTokenInstance']
} else {
  checkTokenInstance = new CheckToken()
}

export default checkTokenInstance;















